#ifndef _VL_BUFFER__H_
#define _VL_BUFFER__H_


/**
 * +======================================================================================================================+
 * @brief: CimZzz
 * @date: 2024-03-08 10:20:41
 * 
 * vlbuffer 字节缓冲区:
 * 
 * vlbuffer 字节缓冲区, 内部维护基数组来存储实际数据, 提供最基础的:
 * 
 * 1. Random Read & Random Write
 * 
 */

/**
 * @brief: CimZzz
 * @date: 2023-12-29 14:50:41
 * 
 * 编译期间检查 unsigned char 长度必须为 1 个字节, 作为缓冲区的基本单位
 */
static_assert(sizeof(unsigned char) == 1, "size of unsigned char is not 1 byte, cannot use this library");
typedef unsigned char vlbyte;
typedef const vlbyte vlbyte_c;
typedef vlbyte* vlbyte_p;
typedef vlbyte** vlbyte_pp;
typedef vlbyte_c* vlbyte_cp;
typedef vlbyte_cp const * vlbyte_cpp;


#include <cstddef> // size_t 支持
#include <cstdint> // 整型支持
#include <exception> // 异常支持
#include <string> // C++ 字符串支持
#include <cstdarg> // 变长参数支持
#include <iostream> // 输入输出流支持
#include <vector> // STL 向量支持

#define VLBUFFER_INLINE inline
#ifdef VLBUFFER_FEATURE_ASSERT
	#include <cassert> // 断言支持
	#include <cstdio> // 标准输出支持
	#define VLBUFFER_ERROR_CHECK(cond, msg, ...) if(cond) { std::fprintf(stderr, msg "\n", ##__VA_ARGS__); assert(false); }
#else
	#define VLBUFFER_ERROR_CHECK(cond, msg, ...) if(cond) throw VL::vlbuffer_exception(msg, ##__VA_ARGS__);
#endif

#if defined __APPLE__ || defined __MACH__
	// 平台常量
	#define __VL_BUFFER_FEATURE_APPLE
#elif defined __linux__ || defined __unix || defined __unix__
	// 平台常量
	#define __VL_BUFFER_FEATURE_UNIX
#elif defined _WIN32 || defined _WIN64
#else
#endif

namespace VL {

/**
 * @brief: CimZzz
 * @date: 2024-04-11 18:36:57
 * 
 * 字节缓冲区异常
 */
class vlbuffer_exception: public std::exception {
public:
	explicit vlbuffer_exception(const char * msg, ...);
    virtual const char* what() const _NOEXCEPT;
private:
	std::string msg;
};

/**
 * @brief: CimZzz
 * @date: 2024-04-15 15:48:13
 * 
 * 字节缓冲区位置信息
 * 用于查找
 */
struct vlbuffer_position {
	bool is_found;
	size_t begin_idx;
	size_t end_idx;

	VLBUFFER_INLINE operator bool() const { return this->is_found; }
};

/**
 * @brief: CimZzz
 * @date: 2024-04-17 10:50:17
 * 
 * 字节缓冲区位置信息
 * 用于多匹配查找
 */
struct vlbuffer_multi_position {
	bool is_found;
	vlbyte_cp found_mbs;
	vlbyte found_idx;
	size_t begin_idx;
	size_t end_idx;

	VLBUFFER_INLINE operator bool() const { return this->is_found; }
};

/**
 * @brief: CimZzz
 * @date: 2024-04-17 14:08:03
 * 
 * 字节缓冲区多字节多匹配数据集合体
 * 用于多匹配查找
 */
struct vlbuffer_find_matcher {
	VLBUFFER_INLINE vlbuffer_find_matcher(vlbyte_cp mbs, size_t mbs_len): b(0), mbs(mbs), mbs_len(mbs_len) {}
	VLBUFFER_INLINE vlbuffer_find_matcher(vlbyte b): b(b), mbs((vlbyte_cp)&this->b), mbs_len(1) {}
	vlbuffer_find_matcher(char c);
	vlbuffer_find_matcher(const char* str);
	vlbuffer_find_matcher(const char* str, size_t len);
	vlbyte b;
	vlbyte_cp mbs;
	size_t mbs_len;
};

struct vlbuffer_print_option {
	/**
	 * @brief: CimZzz
	 * @date: 2023-12-05 15:34:47
	 * 
	 * 打印前缀标志位
	 */
	static constexpr unsigned int PRINT_PREFIX = 0x1;

	/**
	 * @brief: CimZzz
	 * @date: 2023-12-05 15:35:10
	 * 
	 * 打印统一格式字节标志位, 比如打印 16 进制时, 如果字节转成 16 进制字符不足两位时, 将自动在前方补 0
	 */
	static constexpr unsigned int PRINT_UNIFY = 0x2;

	/**
	 * @brief: CimZzz
	 * @date: 2023-12-05 15:36:25
	 * 
	 * 打印大写标志位
	 */
	static constexpr unsigned int PRINT_UPPER_CASE = 0x4;

	/**
	 * @brief: CimZzz
	 * @date: 2023-12-05 15:36:39
	 * 
	 * 打印地址标志位
	 */
	static constexpr unsigned int PRINT_ADDRESS = 0x8;

	/**
	 * @brief: CimZzz
	 * @date: 2023-12-05 15:36:50
	 * 
	 * 打印进程地址标志位
	 */
	static constexpr unsigned int PRINT_PROC_ADDRESS = 0x18;

	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 11:56:12
	 * 
	 * 打印字节偏移值
	 */
	size_t offset = 0;

	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 11:56:24
	 * 
	 * 打印字节长度
	 */
	size_t len = 0;
	
	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 11:56:45
	 * 
	 * 指定字节数, 每打印指定数换行
	 * 
	 * @note 指定为 0 表示不换行
	 */
	unsigned int break_count = 16;

	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 12:04:29
	 * 
	 * 打印字节的进制形式
	 * 
	 * 默认为 16 进制, 取值范围应为 2 ~ 36
	 */
	unsigned char radix = 16;

	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 15:22:32
	 * 
	 * 打印符号位, 参见 [PRINT_*] 定义的静态常量
	 */
	unsigned int flag = PRINT_PREFIX | PRINT_UNIFY | PRINT_UPPER_CASE;

	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 12:21:21
	 * 
	 * 指定打印一致性填充所用字符
	 */
	char unify_code = '0';

	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 12:10:58
	 * 
	 * 打印字节前缀, 如果不指定, 则会使用默认前缀, 如:
	 * 
	 * 2 进制: 0b
	 * 8 进制: 0
	 * 16进制: 0x
	 * 24进制: 0t
	 * 36进制: 0k
	 * 
	 * 若未指定前缀, 且不在上述几个进制中, 则会不显示前缀
	 */
	const char * prefix = nullptr;

	/**
	 * @brief: CimZzz
	 * @date: 2023-11-22 12:17:53
	 * 
	 * 打印字节分隔符, 默认为空格
	 */
	const char * separator = " ";
};

/**
 * @brief: CimZzz
 * @date: 2024-04-19 18:07:45
 * 
 * 字节缓冲区数据源
 */
class vlbuffer_source {
public:
	virtual ~vlbuffer_source () {};
	// 获取字节, sink 是字节接收区, offset 针对 sink, len 表示期望读取字节数
	// 如果获取失败, 需以异常的方式抛出中断
	virtual size_t fetch(vlbyte_p sink, size_t offset, size_t len) = 0;
	VLBUFFER_INLINE int fetch_one_byte() {
		if(!this->can_read()) return -1;
		vlbyte byte;
		if(this->fetch(&byte, 0, 1) != 1) return -1;
		return byte;
	}
	virtual bool can_read() = 0;
};

/**
 * @brief: CimZzz
 * @date: 2024-03-19 15:44:52
 * 
 * 字节缓冲区基类
 */
class vlbuffer_base {
protected:
	explicit VLBUFFER_INLINE vlbuffer_base(): _buf(nullptr), _total_len(0), _write_idx(0) {};
	explicit VLBUFFER_INLINE vlbuffer_base(vlbyte_p buf, size_t total_len): _buf(buf), _total_len(total_len), _write_idx(0) {};
	virtual ~vlbuffer_base();

public:

	VLBUFFER_INLINE size_t total_len() const { return this->_total_len; }
	VLBUFFER_INLINE size_t size() const { return this->_total_len; }
	VLBUFFER_INLINE size_t length() const { return this->_total_len; }
	VLBUFFER_INLINE vlbyte_p ptr() { return this->_buf; }
	VLBUFFER_INLINE vlbyte_cp ptr() const { return this->_buf; }
	VLBUFFER_INLINE char * c_ptr() { return (char *)this->_buf; }
	VLBUFFER_INLINE const char * c_ptr() const { return (const char *)this->_buf; }
	// 解引用
	VLBUFFER_INLINE vlbyte_p operator*() { return this->_buf; }
	VLBUFFER_INLINE vlbyte_cp operator*() const { return this->_buf; }
	// 取下标
	VLBUFFER_INLINE vlbyte& operator[](size_t index) {
		VLBUFFER_ERROR_CHECK(index >= this->_total_len, "out of vlbuffer bounded, index is %zu, but buffer total length is %zu", index, this->_total_len);
		return this->_buf[index];
	}
	VLBUFFER_INLINE const vlbyte& operator[](size_t index) const {
		VLBUFFER_ERROR_CHECK(index >= this->_total_len, "out of vlbuffer bounded, index is %zu, but buffer total length is %zu", index, this->_total_len);
		return this->_buf[index];
	}
	// 填充字节 & 多字节
	void fill_byte(vlbyte byte, size_t offset, size_t nitems);
	void fill_mbs(vlbyte_cp bytes, size_t len, size_t offset, size_t nitems);

	// 复制字节
	void copy_from(vlbyte_cp from, size_t offset, size_t len);
	// 拷出字节
	void copy_to(vlbyte_p to, size_t offset, size_t len) const;
	// void clip(size_t offset, size_t len);
	// 寻找单字节 & 多字节在字节缓冲区中的位置
	vlbuffer_position find(const vlbuffer_find_matcher& matcher, size_t offset = 0, size_t len = 0) const;
	vlbuffer_multi_position find_multi(const std::vector<vlbuffer_find_matcher>& search_mbs_arr, size_t offset = 0, size_t len = 0) const;

	// 判断以 ... 开头
	vlbuffer_position start_with(const vlbuffer_find_matcher& matcher, size_t offset = 0) const;
	vlbuffer_multi_position start_with_multi(const std::vector<vlbuffer_find_matcher>& search_mbs_arr, size_t offset = 0) const;

	// 追加字节方法
	template<typename T, typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
	VLBUFFER_INLINE void append(T value) {
		size_t type_len = sizeof(T);
		this->copy_from((vlbyte_cp)&value, this->_write_idx, type_len);
		this->_write_idx += type_len;
	}

	void append(const char * str, size_t offset = 0, size_t len = 0);
	void append(const std::string& str, size_t offset = 0, size_t len = 0);
	void append(const vlbuffer_base& buf, size_t offset = 0, size_t len = 0);

	size_t append(vlbuffer_source& source, size_t read_len = 0, size_t read_buf_size = 0);
	size_t append_until(vlbuffer_source& source, const vlbuffer_find_matcher& matcher, size_t read_len = 0, size_t read_buf_size = 0);

	size_t append(std::istream& in, size_t read_len = 0, size_t read_buf_size = 0);
	size_t append_until(std::istream& in, const vlbuffer_find_matcher& matcher, size_t read_len = 0, size_t read_buf_size = 0);

	#if defined __VL_BUFFER_FEATURE_APPLE || defined __VL_BUFFER_FEATURE_UNIX
	// 读 fd
	// len 表示读取字节数
	// read_buf_size 表示每次读的字节数, 默认 1024
	// 直到读取至 EOF 或指定字节数时结束
	size_t append_fd(int fd, size_t read_len = 0, size_t read_buf_size = 0);
	size_t append_fd_until(int fd, const vlbuffer_find_matcher& matcher, size_t read_len = 0, size_t read_buf_size = 0);
	#endif

	template<typename T>
	VLBUFFER_INLINE vlbuffer_base& operator +(T&& value) {
		this->append(std::forward<T>(value));
		return *this;
	}
	template<typename T>
	VLBUFFER_INLINE vlbuffer_base& operator <<(T&& value) {
		this->append(std::forward<T>(value));
		return *this;
	}

	// 写下标相关方法
	VLBUFFER_INLINE size_t idx_write() const { return this->_write_idx; }
	VLBUFFER_INLINE size_t len_write() const { return this->_write_idx; }
	VLBUFFER_INLINE void idx_write_set(size_t idx) { this->_write_idx = idx; }
	VLBUFFER_INLINE void idx_write_next(size_t idx) { this->_write_idx += idx; }
	VLBUFFER_INLINE void idx_write_prev(size_t idx) { this->_write_idx = (this->_write_idx < idx) ? 0 : this->_write_idx - idx; }

	// 打印字节方法
	void print(std::ostream& stream = std::cout, const vlbuffer_print_option& options = {}) const;
protected:
	friend class vlbuffer_reader_core;
	friend class vlbuffer_reader;
	inline void check_cap(size_t target_cap) {
		if(target_cap > this->_total_len) {
			this->expand_cap(target_cap);
		}
	}
	virtual void expand_cap(size_t target_cap) = 0;

	vlbyte_p _buf;
	size_t _total_len;
	size_t _write_idx;
};

class vlbuffer_reader;

/**
 * @brief: CimZzz
 * @date: 2024-04-17 15:23:06
 * 
 * 字节缓冲区读取器核心
 */
class vlbuffer_reader_core {
public:
	VLBUFFER_INLINE explicit vlbuffer_reader_core(const vlbuffer_base& buf): _base_buf(buf), _read_idx(0), _read_range(0) {}

	template<typename T, typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
	VLBUFFER_INLINE T read() {
		size_t type_len = sizeof(T);
		T value;
		this->_base_buf.copy_to((vlbyte_p) &value, this->_read_idx, type_len);
		this->_read_idx += type_len;
		return value;
	}
	template<typename T, typename std::enable_if<std::is_arithmetic<T>::value, bool>::type = true>
	VLBUFFER_INLINE void read(T& value) {
		size_t type_len = sizeof(T);
		this->_base_buf.copy_to((vlbyte_p) &value, this->_read_idx, type_len);
		this->_read_idx += type_len;
	}
	void read_until(vlbuffer_base& dest, const vlbuffer_find_matcher& matcher);
	VLBUFFER_INLINE void read_until(vlbuffer_base& dest, vlbyte search_byte) {
		this->read_until(dest, vlbuffer_find_matcher(search_byte));
	}
	VLBUFFER_INLINE void read_until(vlbuffer_base& dest, char search_byte) {
		this->read_until(dest, vlbuffer_find_matcher(search_byte));
	}
	VLBUFFER_INLINE void read_until(vlbuffer_base& dest, vlbyte_cp search_mbs, size_t search_len) {
		this->read_until(dest, vlbuffer_find_matcher(search_mbs, search_len));
	}
	VLBUFFER_INLINE void read_until(vlbuffer_base& dest, const char * search_mbs, size_t search_len) {
		this->read_until(dest, vlbuffer_find_matcher(search_mbs, search_len));
	}
	VLBUFFER_INLINE void read_until(vlbuffer_base& dest, const char * search_mbs) {
		this->read_until(dest, vlbuffer_find_matcher(search_mbs));
	}


	// 读下标相关方法
	VLBUFFER_INLINE void idx_read_range(size_t range) { this->_read_range = range; }
	VLBUFFER_INLINE size_t idx_read() const { return this->_read_idx; }
	VLBUFFER_INLINE void idx_read_set(size_t idx) { this->_read_idx = idx; }
	VLBUFFER_INLINE void idx_read_next(size_t idx) { this->_read_idx += idx; }
	VLBUFFER_INLINE void idx_read_prev(size_t idx) { this->_read_idx = (this->_read_idx < idx) ? 0 : this->_read_idx - idx; }
	VLBUFFER_INLINE bool read_eof() const { return this->_read_idx >= this->_base_buf._total_len || (this->_read_range != 0 && this->_read_idx >= this->_read_range); }
	vlbuffer_reader reader() const;
protected:
	const vlbuffer_base& _base_buf;
	size_t _read_idx;
	size_t _read_range;
};

/**
 * @brief: CimZzz
 * @date: 2024-04-17 14:34:05
 * 
 * 字节缓冲区读取器
 * 如果字节缓冲区存在 const 限定, 可以使用该读取器在只读情况下读取内部字节
 */
class vlbuffer_reader: public vlbuffer_reader_core {
public:
	VLBUFFER_INLINE vlbuffer_reader(const vlbuffer_base& buf): vlbuffer_reader_core(buf) {}

	VLBUFFER_INLINE size_t total_len() const { return this->_base_buf.total_len(); }
	VLBUFFER_INLINE size_t size() const { return this->_base_buf.size(); }
	VLBUFFER_INLINE size_t length() const { return this->_base_buf.length(); }
	VLBUFFER_INLINE vlbyte_cp ptr() const { return this->_base_buf.ptr(); }
	VLBUFFER_INLINE const char * c_ptr() const { return this->_base_buf.c_ptr(); }
	VLBUFFER_INLINE vlbyte_cp operator*() const { return this->_base_buf.operator*(); }
	VLBUFFER_INLINE const vlbyte& operator[](size_t index) const { return this->_base_buf.operator[](index); }
	VLBUFFER_INLINE void copy_to(vlbyte_p to, size_t offset, size_t len) const { this->_base_buf.copy_to(to, offset, len); }
	VLBUFFER_INLINE vlbuffer_position find(const vlbuffer_find_matcher& matcher, size_t offset = 0, size_t len = 0) const {
		return this->_base_buf.find(matcher, offset, len);
	}
	VLBUFFER_INLINE vlbuffer_multi_position find_multi(const std::vector<vlbuffer_find_matcher>& search_mbs_arr, size_t offset = 0, size_t len = 0) const {
		return this->_base_buf.find_multi(search_mbs_arr, offset, len);
	}
};

/**
 * @brief: CimZzz
 * @date: 2024-04-15 17:33:24
 * 
 * 字节缓冲区
 * 支持动态扩容
 */
class vlbuffer: public vlbuffer_base, public vlbuffer_reader_core {
public:
	explicit vlbuffer();
	explicit vlbuffer(size_t init_cap);
	explicit vlbuffer(const vlbuffer& buf);
	explicit vlbuffer(vlbuffer&& buf);
	explicit vlbuffer(const vlbuffer_base& buf);
	virtual ~vlbuffer();

	void operator=(const vlbuffer& buf);
	void operator=(vlbuffer&& buf);
	void operator=(const vlbuffer_base& buf);

	// 重置
	void reset();

	// 释放资源
	void release();
protected:
	virtual void expand_cap(size_t target_cap) override;
};

/**
 * @brief: CimZzz
 * @date: 2024-04-17 10:57:28
 * 
 * 字节缓冲区
 * 不支持动态扩容, 容量固定
 */
template<size_t fix_cap>
class vlfixedbuffer: public vlbuffer_base, public vlbuffer_reader_core {
public:
	explicit vlfixedbuffer(): vlbuffer_base(this->_fixed_buf, fix_cap), vlbuffer_reader_core(*dynamic_cast<vlbuffer_base *>(this)) {};
	void operator=(const vlbuffer_base& buf) {
		this->_write_idx = 0;
		this->_read_idx = 0;
		this->append(buf);
	}
protected:
	virtual void expand_cap(size_t target_cap) override {
		VLBUFFER_ERROR_CHECK(false, "fixed buffer cannot expand capacity. total is %zu, buf require is %zu", target_cap, this->_total_len);
	}
	vlbyte _fixed_buf[fix_cap];
};

}


#endif